import { CameraView, useCameraPermissions, Camera } from "expo-camera";
import React, { useState, useEffect, useRef, useCallback } from "react";
import { GestureHandlerRootView } from "react-native-gesture-handler";
import { Audio } from "expo-av";
import MaterialIcons from "@expo/vector-icons/MaterialIcons";
import styles from "./index.style";
import { useTheme } from "@/contexts/ThemeContext";
import {
  Text,
  View,
  Animated,
  Easing,
  Dimensions,
  Alert,
  Pressable,
  StyleSheet,
  Button,
} from "react-native";
import { LinearGradient } from "expo-linear-gradient";
import { router } from "expo-router";
import * as ImagePicker from "expo-image-picker";
import MaterialCommunityIcons from "@expo/vector-icons/MaterialCommunityIcons";
import { Gesture, GestureDetector } from "react-native-gesture-handler";
import {
  useSharedValue,
  useAnimatedStyle,
  withTiming,
} from "react-native-reanimated";
import { toQueryString } from "@/utils/url-utils";

const SCREEN_WIDTH = Dimensions.get("window").width;
const SCREEN_HEIGHT = Dimensions.get("window").height;
const TARGET_QRCODE_RATIO = 0.3;
const MIN_HARDWARE_ZOOM = 0;
const MAX_HARDWARE_ZOOM = 1;
const SOFTWARE_ZOOM_FACTOR = 2;

interface Device {
  deviceName: string;
  deviceType: number;
}

export interface QrScanResult {
  qrId: string;
  status: number;
  type: number;
  device?: Device;
  createTime?: string;
  expireTime?: string;
  location?: string; // 位置
}

export default function ScanningPage() {
  const { colors } = useTheme();

  // region Refs & States
  const cameraRef = useRef<CameraView>(null);
  const scanAnimation = useRef(new Animated.Value(0)).current;
  const [torch, setTorch] = useState(false);
  const [scanSuccess, setScanSuccess] = useState(false);
  const lastZoomTime = useRef(Date.now());
  const isMounted = useRef(true);

  // 双重缩放控制
  const hardwareZoom = useSharedValue(MIN_HARDWARE_ZOOM);
  const softwareZoom = useSharedValue(1);

  // region 手势处理
  // 双指缩放手势（硬件变焦）
  const pinchGesture = Gesture.Pinch()
    .onStart(() => {
      hardwareZoom.value = Math.min(hardwareZoom.value, MAX_HARDWARE_ZOOM);
    })
    .onUpdate((e) => {
      const sensitivity = 0.3;
      const newZoom = hardwareZoom.value + (e.scale - 1) * sensitivity;
      hardwareZoom.value = Math.max(
        MIN_HARDWARE_ZOOM,
        Math.min(newZoom, MAX_HARDWARE_ZOOM)
      );
    })
    .onEnd(() => {
      hardwareZoom.value = withTiming(hardwareZoom.value, { duration: 100 });
    });

  // 双击手势（软件缩放切换）
  const doubleTapGesture = Gesture.Tap()
    .numberOfTaps(2)
    .onEnd(() => {
      softwareZoom.value = softwareZoom.value === 1 ? SOFTWARE_ZOOM_FACTOR : 1;
      softwareZoom.value = withTiming(softwareZoom.value, { duration: 300 });
    });

  // 组合手势
  const composedGestures = Gesture.Simultaneous(pinchGesture, doubleTapGesture);

  // 软件缩放动画样式
  const softwareZoomStyle = useAnimatedStyle(() => ({
    transform: [{ scale: softwareZoom.value }],
  }));

  // region 扫码处理
  const handleBarCodeScanned = useCallback(
    async (scanningResult: any) => {
      if (scanSuccess || !scanningResult?.bounds) return;
      if (Date.now() - lastZoomTime.current < 1000) return;

      // 计算综合缩放比例
      const totalZoom = hardwareZoom.value * softwareZoom.value;
      const qrWidth = scanningResult.bounds.size.width * totalZoom;
      const screenRatio = qrWidth / SCREEN_WIDTH;

      if (screenRatio >= TARGET_QRCODE_RATIO * 0.7) {
        handleValidScan(scanningResult.data);
      }
    },
    [scanSuccess, hardwareZoom, softwareZoom]
  );

  // region 扫描成功处理
  const handleValidScan = useCallback(async (data: string) => {
    if (!isMounted.current) return;
    setScanSuccess(true);

    try {
      const { sound } = await Audio.Sound.createAsync(
        require("@/asserts/audio/scan-sound.mp3")
      );
      await sound.playAsync();
      sound.unloadAsync();
      let result: QrScanResult | null = null;
      try {
        result = JSON.parse(data);
        console.log("扫描结果:", result);
        // 解析成功，跳转到login
        setTimeout(() => {
          isMounted.current &&
            router.replace(
              `/scan/result?result=${encodeURIComponent(
                JSON.stringify(result)
              )}`
            );
        }, 500);
      } catch (e) {
        // 解析失败，跳转到other
        setTimeout(() => {
          isMounted.current &&
            router.replace(
              `/scan/result/other?result=${encodeURIComponent(data)}`
            );
        }, 500);
      }
    } finally {
      setScanSuccess(false);
    }
  }, []);

  // region 相册选择
  const handleUsePhoto = useCallback(async () => {
    try {
      const { status } =
        await ImagePicker.requestMediaLibraryPermissionsAsync();
      if (status !== "granted") {
        Alert.alert("需要相册权限");
        return;
      }

      const result = await ImagePicker.launchImageLibraryAsync({
        mediaTypes: ImagePicker.MediaTypeOptions.Images,
        quality: 1,
      });
      if (!result.canceled && result.assets[0].uri) {
        const scannedData = await Camera.scanFromURLAsync(result.assets[0].uri);
        if (scannedData && scannedData.length > 0) {
          handleValidScan(scannedData[0].data);
        }
      }
    } catch (error) {
      console.warn("相册选择错误:", error);
    }
  }, [handleValidScan]);

  // region 扫描动画
  useEffect(() => {
    const animation = Animated.loop(
      Animated.timing(scanAnimation, {
        toValue: 1,
        duration: 3000,
        easing: Easing.linear,
        useNativeDriver: true,
      })
    );
    animation.start();
    return () => animation.stop();
  }, []);

  // region 权限处理
  const [permission, requestPermission] = useCameraPermissions();
  if (!permission?.granted) {
    return (
      <View style={[styles.container, { backgroundColor: colors.background }]}>
        <Text style={[styles.message, { color: colors.text.primary }]}>
          需要相机权限
        </Text>
        <Button
          title="授权"
          onPress={requestPermission}
          color={colors.primary}
        />
      </View>
    );
  }

  const iconColor = colors.text.white;

  return (
    <GestureHandlerRootView style={{ flex: 1 }}>
      <GestureDetector gesture={composedGestures}>
        <View
          style={[styles.container, { backgroundColor: colors.background }]}
        >
          <CameraView
            ref={cameraRef}
            style={StyleSheet.absoluteFill}
            facing="back"
            zoom={hardwareZoom.value}
            enableTorch={torch}
            onCameraReady={() => {
              hardwareZoom.value = MIN_HARDWARE_ZOOM;
              softwareZoom.value = 1;
            }}
            barcodeScannerSettings={{
              barcodeTypes: ["qr"],
            }}
            onBarcodeScanned={scanSuccess ? undefined : handleBarCodeScanned}
          >
            <Animated.View style={[StyleSheet.absoluteFill, softwareZoomStyle]}>
              {/* 扫描框 */}
              <View
                style={[
                  styles.scanFrame,
                  { borderColor: "rgba(255,255,255,0.3)" },
                ]}
              >
                <Animated.View
                  style={[
                    styles.scanLine,
                    {
                      transform: [
                        {
                          translateY: scanAnimation.interpolate({
                            inputRange: [0, 1],
                            outputRange: [0, SCREEN_HEIGHT * 0.4],
                          }),
                        },
                      ],
                      opacity: scanAnimation.interpolate({
                        inputRange: [0, 0.5, 1],
                        outputRange: [0, 1, 0],
                      }),
                    },
                  ]}
                >
                  <LinearGradient
                    colors={[
                      "rgba(0,255,255,0)",
                      "rgba(0,255,255,0.8)",
                      "rgba(0,255,255,0)",
                    ]}
                    style={StyleSheet.absoluteFill}
                  />
                </Animated.View>

                <View
                  style={[
                    styles.corner,
                    styles.topLeft,
                    { borderColor: colors.primary },
                  ]}
                />
                <View
                  style={[
                    styles.corner,
                    styles.topRight,
                    { borderColor: colors.primary },
                  ]}
                />
                <View
                  style={[
                    styles.corner,
                    styles.bottomLeft,
                    { borderColor: colors.primary },
                  ]}
                />
                <View
                  style={[
                    styles.corner,
                    styles.bottomRight,
                    { borderColor: colors.primary },
                  ]}
                />
              </View>

              {/* 控制按钮 */}
              <View style={styles.controls}>
                <Pressable
                  style={[
                    styles.button,
                    { backgroundColor: colors.button.secondary },
                  ]}
                  onPress={handleUsePhoto}
                >
                  <MaterialCommunityIcons
                    name="image-multiple"
                    size={28}
                    color={iconColor}
                  />
                  <Text
                    style={[styles.buttonText, { color: colors.text.white }]}
                  >
                    相册
                  </Text>
                </Pressable>
                <Pressable
                  style={[
                    styles.button,
                    { backgroundColor: colors.button.secondary },
                  ]}
                  onPress={() => setTorch(!torch)}
                >
                  <MaterialIcons
                    name={torch ? "flash-on" : "flash-off"}
                    size={28}
                    color={iconColor}
                  />
                  <Text
                    style={[styles.buttonText, { color: colors.text.white }]}
                  >
                    {torch ? "关闭" : "照亮"}
                  </Text>
                </Pressable>
              </View>
            </Animated.View>
          </CameraView>

          <Text style={[styles.distanceTip, { color: colors.text.white }]}>
            请将二维码/条形码放入框内,即可自动扫描
          </Text>
        </View>
      </GestureDetector>
    </GestureHandlerRootView>
  );
}
